package com.chenfan.magic.interpreter;

import com.chenfan.magic.core.IdcEngineEntry;
import com.chenfan.magic.core.MagicLogPublisher;
import com.chenfan.magic.entity.TTLDetailModel;
import com.chenfan.magic.utils.Charsets;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Map;

/**
 * shell 解释器
 * <p>
 * 示例: run("python ./pythonSrc/time.py caohui 25", 0);
 *
 * @author caohui
 */
@Slf4j
@Component
@AllArgsConstructor
public class ShellInterpreter implements __IInterpreter {

    public static final String TYPE_CODE = "shell";
    public static final String ALIAS = "command";

    @Override
    public Object run(Map<String, Object> idcRuntimePool, String expression, String defaultValue) {
        TTLDetailModel ttlDetailModel = new TTLDetailModel();
        ttlDetailModel.start();
        Object result = null;

        BufferedReader bReader = null;
        InputStreamReader sReader = null;
        try {
            Process p = Runtime.getRuntime().exec(expression.split(" "));

            /* 为"错误输出流"单独开一个线程读取之,否则会造成标准输出流的阻塞 */
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    String line;
                    int num = 0;
                    try {
                        BufferedReader bReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(p.getErrorStream()), Charsets.UTF_8_NAME));
                        StringBuilder sb = new StringBuilder();
                        while ((line = bReader.readLine()) != null) {
                            sb.append(String.format("%02d", num++) + line);
                            sb.append("\n");
                            System.out.println("---->" + String.format("%02d", num++) + " " + line);
                        }
                        String tmp = sb.toString();
                        bReader.close();
                        MagicLogPublisher.publishInterpreterEvent(TYPE_CODE, expression, tmp, null, ttlDetailModel.end().getTtl() + "", null, true);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            });
            thread.start();

            /* 标准输出流"就在当前方法中读取 */
            BufferedInputStream bis = new BufferedInputStream(p.getInputStream());
            sReader = new InputStreamReader(bis, Charsets.UTF_8_NAME);
            bReader = new BufferedReader(sReader);

            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = bReader.readLine()) != null) {
                sb.append(line);
                sb.append("\n");
            }
            bReader.close();
            p.destroy();
            result = sb.toString();
            MagicLogPublisher.publishInterpreterEvent(TYPE_CODE, expression, result, null, ttlDetailModel.end().getTtl() + "");
        } catch (Exception e) {
            e.printStackTrace();
            IdcEngineEntry.throwException(idcRuntimePool, null, e);
            MagicLogPublisher.publishInterpreterEvent(TYPE_CODE, expression, result, null, ttlDetailModel.end().getTtl() + "", e);
        }
        return result != null ? result : defaultValue;
    }

    @Override
    public Object run(Map<String, Object> idcRuntimePool, String code, Map<String, Object> paramMap) {
        return null;
    }

}

